//@author A0097555N

#ifndef logic_H
#define logic_H

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <assert.h>
#include <sstream>
#include <stack>
#include "Task.h"
#include "StatusMessages.h"
#include "FileHandler.h"
#include "Storage.h"
#include "help.h"
#include "interpreter.h"

using namespace std;

class Logic {
public:

	enum COMMAND_TYPE {
		ADD_TASK, DELETE_TASK, EXIT_FILE, INVALID_ERROR, SEARCH, DISPLAY_TASK, CLEAR_FILE,
		RENAME_TASK, RESCHEDULE_TASK, RELOCATE_TASK, MARK_TASK, UNMARK_TASK, UNDO_TASK, REDO_TASK, DISPLAY_HELP
	};

	char buffer[255];
	
	COMMAND_TYPE determineCommand(string command);
	int execute(string inputString, string *output);
	int executeUndoRedo(string inputString, string *output, string *tempUndoCommand);

	Logic(void);

	~Logic(void);

	int interfaceProcesser();

	static const string DELIMITERS;

	int retrieveOldInfo ();
	int Exiting (); 


	int add(vector<string> input, string *output, string *tempUndoCommand);
	int deleter(vector<string> input, string *output, string *tempUndoCommand);
	int rename(vector<string> input, string *output, string *tempUndoCommand);
	int reschedule(vector<string> input, string *output, string *tempUndoCommand);
	int relocate(vector<string> input, string *output, string *tempUndoCommand);
	int markTask(vector<string> input, string *output, string *tempUndoCommand);
	int unmarkTask(vector<string> input, string *output, string *tempUndoCommand);
	
	int display(vector<string> input, string *output, vector<Task>& _tempStorage);
	int clear();
	int search(vector<string> input, string *output);
	int showHelp(string helpType, string* output);

	int undo(string *output);
	int redo(string *output);

	int exitFile();
	int invalid();

	string printEmptySlots(vector<string> emptySlotVector);
	string displayPrinter(vector<Task> _tempStorage);
	string printTaskInfo(vector<string> taskDetails);
	void changeFormatOfTimeForDisplay (vector<string> &timeFromStorage);
	string callDidYouMean(string input);
	int getIndexinInt(string input);

	vector<string> getTaskDetails(string inputString, string *command, int* returnFlag);

	string undoCommandForAdd (string taskName);
	string undoCommandForDelete (vector<string> TaskDetails);
	string undoCommandForRename (string nameBeforeRename, string nameAfterRename);
	string undoCommandForReschedule (vector<string> taskDetailsBeforeReschedule);
	string undoCommandForRelocate (string taskName, string locationBeforeRelocate);

	string undoCommandForMark (string taskName);
	string undoCommandForUnmark (string taskName);

	string toLowerString (string input);

private:

	static const string COMMAND_ADD;
	static const string COMMAND_DELETE;
	static const string COMMAND_DISPLAY;
	static const string COMMAND_EXIT;
	static const string COMMAND_SORT;
	static const string COMMAND_SEARCH;
	static const string COMMAND_CLEAR;
	static const string COMMAND_MARK;
	static const string COMMAND_RENAME;
	static const string COMMAND_RESCHEDULE;
	static const string COMMAND_RELOCATE;
	static const string COMMAND_UNMARK;
	static const string COMMAND_UNDO;
	static const string COMMAND_REDO;
	static const string COMMAND_HELP;


	static const string COMMAND_SHORT_ADD;
	static const string COMMAND_SHORT_DELETE;
	static const string COMMAND_SHORT_DISPLAY;
	static const string COMMAND_SHORT_EXIT;
	static const string COMMAND_SHORT_SEARCH;
	static const string COMMAND_SHORT_UNMARK;
	static const string COMMAND_SHORT_UNDO;
	static const string COMMAND_SHORT_REDO;
	static const string COMMAND_SHORT_RENAME;
	static const string COMMAND_SHORT_RESCHEDULE;
	static const string COMMAND_SHORT_RELOCATE;
	static const string COMMAND_SHORT_MARK;

	static const string COMMAND_SEARCH_OVERLOAD_EMPTY;
	static const string COMMAND_SEARCH_OVERLOAD_RANGE;
	static const string COMMAND_DISPLAY_OVERLOAD_TODAY;
	static const string COMMAND_DISPLAY_OVERLOAD_TODAY_SHORT;


	static const string IDENTIFIER_VENUE;
	static const string IDENTIFIER_START_TIME;
	static const string IDENTIFIER_END_TIME_TO;
	static const string IDENTIFIER_END_TIME_BY;
	static const string IDENTIFIER_RENAME;

	static const string MESSAGE_DID_YOU_MEAN;
	static const string MESSAGE_DID_YOU_MEAN_FOLLOW;
	static const string INVALID_COMMAND;
	static const string MESSAGE_TASK_RENAME;			
	static const string WORD_FROM;
	static const string WORD_TO;	
	static const string MESSAGE_UPDATED_TASK;
	static const string MESSAGE_TASK_ADDED;
	static const string MESSAGE_DELETED;

	static const int INVALID_INDEX;
	static const string SPACE;

	vector<Task> _tempStorage;
	Storage _storage;
	FileHandler _fileProcessing;

	stack<string> historyCommands; 
	stack<string> undoCommands;
	stack<string> redoCommands;	
};

#endif



